refactor(webhooks): extract provider-specific logic into handler registry#3973
refactor(webhooks): extract provider-specific logic into handler registry#3973waleedlatif1 wants to merge 18 commits intostagingfrom
Conversation
PR SummaryHigh Risk Overview Moves external subscription lifecycle management into handler methods ( Updates docs ( Reviewed by Cursor Bugbot for commit 220aa91. Configure here. |
️✅ There are no secrets present in this pull request anymore.If these secrets were true positive and are still valid, we highly recommend you to revoke them. 🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request. |
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
f580455 to
6e95981
Compare
|
@greptile |
|
@cursor review |
Greptile SummaryThis PR refactors the webhook processing pipeline by extracting 14+ provider-specific if-chains into a clean handler registry pattern. Each of the 30 providers now lives in its own file under
Confidence Score: 5/5This PR is safe to merge; all prior P0/P1 issues have been resolved and the remaining findings are P2 style items All previous review concerns (any types in three helpers, processTriggerFileOutputs array initializer, duplicate generic file processing, and generic requireAuth behavior) have been addressed. Remaining findings are an unused variable in logging and inline comment style violations — neither affects runtime correctness or security. apps/sim/lib/webhooks/providers/microsoft-teams.ts (unused errorBody in deleteSubscription) and apps/sim/lib/webhooks/providers/airtable.ts (non-TSDoc comments) Important Files Changed
Sequence DiagramsequenceDiagram
participant Client as External Client
participant Route as route.ts
participant Processor as processor.ts
participant Registry as registry.ts
participant Handler as Provider Handler
participant Execution as webhook-execution.ts
Client->>Route: POST /api/webhooks/trigger/{path}
Route->>Processor: handleProviderChallenges(body, request)
Processor->>Registry: getProviderHandler(provider)
Registry-->>Processor: handler
Processor->>Handler: handler.handleChallenge(body, request)
Handler-->>Processor: NextResponse | null
Route->>Processor: findAllWebhooksForPath({path})
Processor-->>Route: webhooksForPath[]
loop For each webhook
Route->>Processor: verifyProviderAuth(webhook, workflow, request)
Processor->>Registry: getProviderHandler(provider)
Registry-->>Processor: handler
Processor->>Handler: handler.verifyAuth(ctx)
Handler-->>Processor: NextResponse(401) | null
Route->>Processor: shouldSkipWebhookEvent(webhook, body)
Processor->>Handler: handler.shouldSkipEvent(ctx)
Handler-->>Processor: boolean
Route->>Processor: queueWebhookExecution(webhook, workflow, body)
Processor->>Handler: handler.matchEvent(ctx)
Handler-->>Processor: true | false | NextResponse
Processor->>Handler: handler.enrichHeaders(ctx, headers)
Processor->>Handler: handler.formatSuccessResponse(providerConfig)
Processor-->>Route: NextResponse(200)
end
Route-->>Client: 200 Webhook processed
Note over Execution: Async job execution
Execution->>Registry: getProviderHandler(provider)
Registry-->>Execution: handler
Execution->>Handler: handler.formatInput(ctx)
Handler-->>Execution: FormatInputResult
Execution->>Handler: handler.processInputFiles(ctx)
Handler-->>Execution: void
Execution->>Execution: executeWorkflowCore(snapshot)
Reviews (7): Last reviewed commit: "refactor(webhooks): standardize logger n..." | Re-trigger Greptile |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 6e95981. Configure here.
|
@cursor review |
|
@greptile |
|
@greptile |
|
@cursor review |
|
@cursor review |
|
@greptile |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 0d116fa. Configure here.
- Restore original fall-through behavior for generic requireAuth with no token - Replace `any` params with proper types in processor helper functions - Restore array-aware initializer in processTriggerFileOutputs
…ggerFileOutputs Cast array initializer to Record<string, unknown> to allow string indexing while preserving array runtime semantics for the return value.
…gured If a user explicitly sets requireAuth: true, they expect auth to be enforced. Returning 401 when no token is configured is the correct behavior — this is an intentional improvement over the original code which silently allowed unauthenticated access in this case.
…e handler Co-locate the ~400-line Airtable payload processing function with its provider handler. Remove AirtableChange interface from utils.server.ts.
…fig.ts Move configureGmailPolling, configureOutlookPolling, configureRssPolling, and configureImapPolling out of utils.server.ts into a dedicated module. Update imports in deploy.ts and webhooks/route.ts.
…rmatInput methods Move all provider-specific input formatting from the monolithic formatWebhookInput switch statement into each provider's handler file. Delete formatWebhookInput and all its helper functions (fetchWithDNSPinning, formatTeamsGraphNotification, Slack file helpers, convertSquareBracketsToTwiML) from utils.server.ts. Create new handler files for gmail, outlook, rss, imap, and calendly providers. Update webhook-execution.ts to use handler.formatInput as the primary path with raw body passthrough as fallback. utils.server.ts reduced from ~1600 lines to ~370 lines containing only credential-sync functions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…istry pattern Move all provider-specific subscription create/delete logic from the monolithic provider-subscriptions.ts into individual provider handler files via new createSubscription/deleteSubscription methods on WebhookProviderHandler. Replace the two massive if-else dispatch chains (11 branches each) with simple registry lookups via getProviderHandler(). provider-subscriptions.ts reduced from 2,337 lines to 128 lines (orchestration only). Also migrate polling configuration (gmail, outlook, rss, imap) into provider handlers via configurePolling() method, and challenge/verification handling (slack, whatsapp, teams) via handleChallenge() method. Delete polling-config.ts. Create new handler files for fathom and lemlist providers. Extract shared subscription utilities into subscription-utils.ts. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…rcation comments - Cast `body` to `Record<string, unknown>` in attio formatInput to fix type error with extractor functions - Restore `rejectUnauthorized` field in imap configurePolling for parity - Remove `// ---` section demarcation comments from route.ts and airtable.ts - Update add-trigger skill to reflect handler-based architecture Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
0d116fa to
8bcf450
Compare
|
@greptile |
|
@cursor review |
…execution The generic provider's processInputFiles handler already handles file[] field processing via the handler.processInputFiles call. The hardcoded block from staging was incorrectly preserved during rebase, causing double processing. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
@greptile |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 60610b7. Configure here.
… at deploy time Rejects deployment with a clear error message if a generic webhook trigger has requireAuth enabled but no authentication token configured, rather than letting requests fail with 401 at runtime. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…olling config The refactored IMAP handler added a rejectUnauthorized field that was not present in the original configureImapPolling function. This would default to true for all existing IMAP webhooks, potentially breaking connections to servers with self-signed certificates. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… handler Per project coding standards, use generateId() from @/lib/core/utils/uuid instead of crypto.randomUUID() directly. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…m providers - Standardize logger names to WebhookProvider:X pattern across 6 providers (fathom, gmail, imap, lemlist, outlook, rss) - Replace all `any` types in airtable handler with proper types: - Add AirtableTableChanges interface for API response typing - Change function params from `any` to `Record<string, unknown>` - Change AirtableChange fields from Record<string, any> to Record<string, unknown> - Change all catch blocks from `error: any` to `error: unknown` - Change input object from `any` to `Record<string, unknown>` Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
@greptile |
|
@cursor review |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 220aa91. Configure here.
| status: 400, | ||
| }, | ||
| } | ||
| } |
There was a problem hiding this comment.
Deploy-time auth check applies to all providers
Medium Severity
A new deploy-time validation checks for requireAuth: true without a token across all trigger blocks. This check was intended for the generic webhook provider, where requireAuth is a specific concept. Workflows with a generic trigger that previously deployed successfully (failing at runtime) now fail at deploy time with a 400 error. This also risks incorrectly blocking future providers.
Reviewed by Cursor Bugbot for commit 220aa91. Configure here.
Replace 3 `catch (error: any)` with `catch (error: unknown)` and 1 `Record<string, any>` with `Record<string, unknown>`. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>


Summary
lib/webhooks/providers/implementing only the methods it needscreateHmacVerifierfactory,verifyTokenAuthhelper,skipByEventTypesfilterverifyProviderWebhookfrom utils.server.ts (merged into per-provider auth)Type of Change
Testing
Checklist